package com.rrd.hive.udf.plist;

import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import java.io.IOException;
import java.util.*;

import static com.rrd.hive.udf.plist.utils.PlistCommon.*;

@Description(
        name = "ato_plist_tags_v2",
        value = "_FUNC_(text) - Creates a map by xml string ",
        extended = "parse tags string to map"
)
public class AtoPlistTagsToMapV2 extends UDF {
    private final static String DIM_PLIST_APPNAME_TAG = "/data/dim/plist_appname_tag";
    private final static String DIM_PLIST_RANK1 = "/data/dim/plist_rank1";
    private final static String DIM_PLIST_RANK2 = "/data/dim/plist_rank2";
    private final static String DIM_PLIST_PACKAGE_NAME_GREY_TAG_NEW = "/data/dim/plist_package_name_grey_tag_new";
    private final static String DIM_PLIST_LOAN_APP_TAG = "/data/dim/plist_loan_app_tag";
    private final static String DIM_PLIST_NOT_LOAN_APP_TAG = "/data/dim/plist_not_loan_app_tag";
    private final static Map<String,String> app_name_tag_map = new HashMap<>(10000);
    private final static Map<String,String> rank1_tag_map = new HashMap<>(1000);
    private final static Map<String,String> rank2_tag_map = new HashMap<>(1000);
    private final static Map<String,String> grey_tag_map = new HashMap<>(1000);
    private final static Map<String,String> loan_tag_map = new HashMap<>(50000);
    private final static Map<String,String> not_loan_tag_map = new HashMap<>(80000);
    private static final List<String> tagsList =
            Arrays.asList("xw_store_tag","xw_type","tier3","tier2","exceptions","tier1","xfjr","bank","exceptions_new");

    static {
        try {
            // 初始化码表数据
            loadDataInMap(app_name_tag_map, DIM_PLIST_APPNAME_TAG);
            loadDataInMap1(rank1_tag_map, DIM_PLIST_RANK1,"\u0001");
            loadDataInMap1(rank2_tag_map, DIM_PLIST_RANK2, "\u0001");
            loadDataInMap1(grey_tag_map, DIM_PLIST_PACKAGE_NAME_GREY_TAG_NEW, "\u0001");
            loadDataInMap1(loan_tag_map, DIM_PLIST_LOAN_APP_TAG,",");
            loadDataInMap1(not_loan_tag_map, DIM_PLIST_NOT_LOAN_APP_TAG,",");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static void loadDataInMap(Map<String,String> map,String filePath) throws IOException {
        final String s = loadDataFromFile(filePath);
        Arrays.stream(s.split("\n", -1)).forEach(lines -> {
            final String[] line = lines.split(",");
            if (line.length >= 2) {
                isExits(app_name_tag_map, line[1].trim(), line[0]);
            }
        });
    }

    private static void loadDataInMap1(Map<String, String> map, String filePath, String split) throws IOException {
        final String s = loadDataFromFile(filePath);
            Arrays.stream(s.split("\n", -1)).forEach(lines -> {
                final String[] line = lines.split(split);
                if (line.length >= 2) {
                    map.put(line[0].trim(), line[1]);
                }
            });
    }

    public Map<String,String> evaluate(String app_name,String apk_name) throws HiveException {
        final Map<String, String> result = new HashMap(1);
        StringBuilder stringBuilder = new StringBuilder();
        String app_tag = null;
        String rank1_tag = null;
        String rank2_tag = null;
        String grey_tag = null;
        String loan_tag = null;
        String not_loan_tag = null;
        if (app_name != null) {
            final String app_name_trim = app_name.trim();
            app_tag = app_name_tag_map.get(app_name_trim);
            rank1_tag = rank1_tag_map.get(app_name_trim);
            rank2_tag = rank2_tag_map.get(app_name_trim);
            grey_tag = grey_tag_map.get(apk_name);
            loan_tag = loan_tag_map.get(app_name_trim);
            not_loan_tag = not_loan_tag_map.get(app_name_trim);
        }
        addFlag(stringBuilder, rank1_tag, "1");
        addFlag(stringBuilder, rank1_tag, "2");
        addFlag(stringBuilder, rank2_tag, "1");
        addFlag(stringBuilder, rank2_tag, "3");
        final boolean b = hiveUdfRegExp(app_name, "粉笔职教|公考雷达|网易云课堂|云课堂智慧职教|智学网 |粉笔教育|优路教育|英语|腾讯课堂|百度文库|网易有道词典|网易公开课|有道精品课|中国大学MOOC|学|网校|辅导|教育|语言|英语|日语|法语|西班牙语|俄罗斯语|葡萄牙语|德语|韩语|阿拉伯语");
        final boolean b1 = hiveUdfRegExp(app_name, "家长|儿童|少儿");
        if (b && !b1) {
            stringBuilder.append(1);
        } else {
            stringBuilder.append(0);
        }
        if (app_tag != null && app_tag.contains("xw_type") && (app_tag.contains("xw_store_tag") || hiveUdfRegExp(app_name,"新闻|News|news|NEWS|报|党|全球|学习|看点|日报|新华社|财经|头条|时报|看点")) && !hiveUdfRegExp(app_name,"腾讯新闻|新浪新闻|今日头条")) {
            stringBuilder.append(1);
        } else {
            stringBuilder.append(0);
        }
        if ("Keep".equals(app_name) || hiveUdfRegExp(app_name, "Fit健身")) {
            stringBuilder.append(1);
        } else {
            stringBuilder.append(0);
        }

        addFlag(stringBuilder, hiveUdfRegExp(app_name, "小红书"));
        addFlag(stringBuilder, hiveUdfRegExp(app_name, "大众点评"));
        addFlag(stringBuilder, hiveUdfRegExp(app_name, "考拉海购|海淘|识货|红布林|寺库奢侈品|洋码头|得物|心心|海外购|玩物得志|医美|免税"));
        addFlag(stringBuilder, hiveUdfRegExp(app_name, "星巴克|luckin coffee|太平洋咖啡|贝瑞咖啡|摩卡星|小鹿茶|喜茶|奈雪的茶|茶颜悦色"));
        addFlag(stringBuilder, hiveUdfRegExp(app_name, "必胜客|海底捞"));
        addFlag(stringBuilder, hiveUdfRegExp(app_name, "盒马|山姆会员|麦德龙"));

        addFlag(stringBuilder, grey_tag, "1");
        addFlag(stringBuilder, loan_tag, "1");
        addFlag(stringBuilder, not_loan_tag, "1");

        String finalApp_tag = app_tag;
        tagsList.forEach(app -> addFlag(stringBuilder, finalApp_tag != null && !"exceptions".equals(app) && finalApp_tag.contains(app)));
        result.put("app_tags_v2",stringBuilder.toString());
        return result;
    }

    private void addFlag(StringBuilder stringBuilder, boolean flag) {
        if (flag) {
            stringBuilder.append(1);
        } else {
            stringBuilder.append(0);
        }
    }

    private void addFlag(StringBuilder stringBuilder, String tag, String num) {
        if (num.equals(tag)) {
            stringBuilder.append(1);
        } else {
            stringBuilder.append(0);
        }
    }

    public String getDisplayString(String[] children) {
        assert children.length == 2;
        return "app_name: " + children[0] + "  " + "apk_name: " + children[1];
    }
}
